package com.pansky.crm.controller.business;

import com.pansky.crm.annotation.OperateLog;
import com.pansky.crm.common.mybatisplus.ApiResult;
import com.pansky.crm.config.redis.RedisBean;
import com.pansky.crm.service.impl.FileService;
import com.pansky.crm.util.TokenUtil;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.List;
import java.util.UUID;

/**
 * @author ：zhouzhiyong
 * @date ：Created in 2021/3/9 15:14
 * @description：文件服务
 */
@Slf4j
@RestController
@RequestMapping("/file")
@OperateLog
@Api(tags = {"管理端-文件管理api"})
public class FileController {

    @Autowired
    private RedisBean redisBean;

    @Autowired
    private FileService fileService;
    /**
     * 上传文件
     * @param file 文件
     * @return 文件地址
     */
    /**
     * 图片上传
     *
     * @param file 文件
     * @return 文件路径
     */
    @PostMapping("/upload")
    public ApiResult<String> fileUpload(HttpServletRequest request, @RequestPart("file") MultipartFile file,
                                        @RequestHeader String token) throws IOException {
        if (file.getSize() > 10 * 1024 * 1024) {
            return ApiResult.failed("上传失败:文件大小不能超过10MB");
        }
        String originalFilename = file.getOriginalFilename();
        // 获取上传文件扩展名
        assert originalFilename != null;
        String fileExt = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        // 对扩展名进行小写转换
        fileExt = fileExt.toLowerCase();
        // 图片文件大小过滤
        if (!"jpg".equals(fileExt) && !"jpeg".equals(fileExt)
                && !"png".equals(fileExt) && !"bmp".equals(fileExt)
                && !"gif".equals(fileExt)) {
            return ApiResult.failed("格式错误，请勿上传非图片文件");
        }
        String localAddr = request.getLocalAddr();
        int serverPort = request.getServerPort();
        String path = ResourceUtils.getURL("classpath:").getPath()+"static" + File.separator + "upload" + File.separator + "image" + File.separator;
        // 获取原始名字
        String fileName = UUID.randomUUID() + file.getOriginalFilename();
        log.info("----file.getOriginalFilename() is {}", fileName);
        // 文件重命名，防止重复
        String realFileName = path + fileName;
        log.info("-----fileName is {}", fileName);
        // 文件对象
        File dest = new File(realFileName);
        log.info("dest path is {}", dest.getAbsolutePath());

        // 判断路径是否存在，如果不存在则创建
        if(!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        try {
            String filePath = "http://" + localAddr +":"+ serverPort + "/upload/image/" + fileName;
            // 保存到服务器中
            String subject = TokenUtil.getTokenBody(token).getSubject();
            redisBean.set("exist_File:" + subject, filePath);
            file.transferTo(dest);
            return ApiResult.ok(filePath);
        } catch (Exception e) {
            log.error("file upload fail", e);
            return ApiResult.failed("上传图片失败");
        }
    }

    @GetMapping("/save")
    public ApiResult<Boolean> saveFile(HttpServletRequest request, @RequestParam String sourceFileName) throws IOException {
        String realPath = request.getServletContext().getRealPath(File.separator);
        String targetFilePath = realPath + File.separator + "imageFile" + File.separator;
        String targetFileName = targetFilePath + sourceFileName.substring(sourceFileName.lastIndexOf(File.separator));
        log.info("---saveFile---targetFileName:{}", targetFileName);
        FileUtils.copyFile(new File(sourceFileName), new File(targetFileName));
        return ApiResult.ok();
    }

    @PostMapping("/delete")
    public ApiResult<Boolean> removeFile(@RequestParam  String filePath, @RequestHeader String token) throws FileNotFoundException {
        return fileService.removeFile(filePath,token);
    }

    @GetMapping("/download")
    public void download(HttpServletResponse response, @RequestParam String filePath) throws Exception {
        // 文件地址，真实环境是存放在数据库中的
        File file = new File(filePath);
        // 穿件输入对象
        FileInputStream fis = new FileInputStream(file);
        // 设置相关格式
        response.setContentType("application/force-download");
        // 设置下载后的文件名以及header
        response.addHeader("Content-disposition", "attachment;fileName=" + file.getName());
        // 创建输出对象
        OutputStream os = response.getOutputStream();
        // 常规操作
        byte[] buf = new byte[1024];
        int len = 0;
        while((len = fis.read(buf)) != -1) {
            os.write(buf, 0, len);
        }
        fis.close();
    }

    @GetMapping("/exist")
    public ApiResult<String> findExistsFile(@RequestHeader String token) {
        String subject = TokenUtil.getTokenBody(token).getSubject();
        String filePath = (String) redisBean.get("exist_File:" + subject);
        return ApiResult.ok(filePath);
    }
}
